/*
 * Author: nicolas.bredeche(@)lri.fr
 * Created on 20 janv. 2006
 * 
 */

package picoevo.gp.representation.genericoperators;

import java.util.ArrayList;

import picoevo.core.representation.Individual;
import picoevo.core.representation.Population;
import picoevo.gp.representation.Element_Node_TreeGP;
import picoevo.gp.representation.Element_Node_TreeGP_Terminal;
import picoevo.toolbox.Display;

public class Element_Node_TreeGP_FunctionCall extends Element_Node_TreeGP_Terminal {

	private int _functionIndex = 0;

	public Element_Node_TreeGP_FunctionCall(Individual __individualOwner, ArrayList __elementLevelOperatorList) {
		super(__individualOwner, __elementLevelOperatorList);
		setArity(0);
		setDisplayValue("FunctionCall");
	}

	@Override
	public double evaluateDouble() {
		ArrayList list = this.getSuccessors();
		if (list.size() != 0)
			Display.error("" + getClass().getName() + "::evaluate() - incorrect number of successors (" + list.size() + ")");

		// ((Individual_TreeGPmodule)(((((ParameterSet_Evolution_mulambdaES_TreeGP_CoEvoMain)this.getTemplate()).getModulePopulation())).getIndividual(this._functionIndex))).incCallCounter();
		// // the module population fitness depends on the number of call

		// call the corresponding module for evaluation
		Element_Node_TreeGP targetNode = (Element_Node_TreeGP) ((Population) ((this.getTemplate()).getObjectProperty("ModulePopulation"))).getIndividual(this._functionIndex).getElementAt(0);
		return (targetNode.evaluateDouble());
	}

	/**
	 * overwrite trace methods to provide fitness evaluation for second "module"
	 * population. See EvaluationOperator_Population_SymRegModule::evaluate()
	 */
	@Override
	public void trace() {
		// the module population fitness depends on the number of call AND this
		// individual's previously computed fitness
		double value = 1 / (1 + this.getOwner().getFitness());
		((Individual_TreeGPmodule) (((Population) (this.getTemplate().getObjectProperty("ModulePopulation"))).getIndividual(this._functionIndex))).updateFitness(value);
	}

	/**
	 * return the index, i.e. the number of the individual-function to call (in
	 * the co-evolved population)
	 * 
	 * @return
	 */
	public int getFunctionIndex() {
		return _functionIndex;
	}

	/**
	 * set the index number of the targetted individual-function to call (in the
	 * co-evolved population)
	 * 
	 * @param functionIndex
	 */
	public void setFunctionIndex(int functionIndex) {
		this._functionIndex = functionIndex;
	}

	@Override
	public String getDisplayValue() {
		String s = new String();

		s = super.getDisplayValue() + "[" + this.getFunctionIndex() + "]{";
		s += ((Element_Node_TreeGP) (((Individual_TreeGPmodule) (((Population) ((this.getTemplate()).getObjectProperty("ModulePopulation"))).getIndividual(this._functionIndex))).getElementAt(0))).getDisplayInformation();
		s += "}";
		return s;
	}
}
